/*
 * rfirtc.c
 *
 *  Created on: Nov 29, 2012
 *      Author: Andrey Belomutskiy
 */


#include "rfirtc.h"

static void stm32_rtc_bcd2tm(struct tm *timp, RTCTime *timespec) {
	uint32_t tv_time = timespec->tv_time;
	uint32_t tv_date = timespec->tv_date;
	uint32_t tv_msec = timespec->tv_msec;

#if CH_DBG_ENABLE_CHECKS
	timp->tm_isdst = 0;
	timp->tm_wday = 0;
	timp->tm_mday = 0;
	timp->tm_yday = 0;
	timp->tm_mon = 0;
	timp->tm_year = 0;
	timp->tm_sec = 0;
	timp->tm_min = 0;
	timp->tm_hour = 0;
#endif

	timp->__extra_1 = tv_msec;

	timp->tm_isdst = -1;

	timp->tm_wday = (tv_date & RTC_DR_WDU ) >> RTC_DR_WDU_OFFSET;
	if (timp->tm_wday == 7)
		timp->tm_wday = 0;

	timp->tm_mday = (tv_date & RTC_DR_DU ) >> RTC_DR_DU_OFFSET;
	timp->tm_mday += ((tv_date & RTC_DR_DT )>> RTC_DR_DT_OFFSET) * 10;

	timp->tm_mon = (tv_date & RTC_DR_MU ) >> RTC_DR_MU_OFFSET;
	timp->tm_mon += ((tv_date & RTC_DR_MT )>> RTC_DR_MT_OFFSET) * 10;
	timp->tm_mon -= 1;

	timp->tm_year = (tv_date & RTC_DR_YU ) >> RTC_DR_YU_OFFSET;
	timp->tm_year += ((tv_date & RTC_DR_YT )>> RTC_DR_YT_OFFSET) * 10;
	timp->tm_year += 2000 - 1900;

	timp->tm_sec = (tv_time & RTC_TR_SU ) >> RTC_TR_SU_OFFSET;
	timp->tm_sec += ((tv_time & RTC_TR_ST )>> RTC_TR_ST_OFFSET) * 10;

	timp->tm_min = (tv_time & RTC_TR_MNU ) >> RTC_TR_MNU_OFFSET;
	timp->tm_min += ((tv_time & RTC_TR_MNT )>> RTC_TR_MNT_OFFSET) * 10;

	timp->tm_hour = (tv_time & RTC_TR_HU ) >> RTC_TR_HU_OFFSET;
	timp->tm_hour += ((tv_time & RTC_TR_HT )>> RTC_TR_HT_OFFSET) * 10;
	timp->tm_hour += 12 * ((tv_time & RTC_TR_PM )>> RTC_TR_PM_OFFSET);
}

time_t rtcGetTimeUnixMs(RTCDriver *rtcp) {
#if STM32_RTC_HAS_SUBSECONDS
	RTCTime timespec = { 0, 0, FALSE, 0 };
#else
	RTCTime timespec = {0,0,FALSE};
#endif
	struct tm timp;

	rtcGetTime(rtcp, &timespec);
	stm32_rtc_bcd2tm(&timp, &timespec);

	return mktime(&timp) * 1000 + timp.__extra_1;
}
